//
//  KDTableViewController.m
//  M800Project
//
//  Created by 姚宗超 on 14/11/6.
//  Copyright (c) 2014年 姚宗超. All rights reserved.
//

#import "KDTableViewController.h"
#import "KDTableViewCell.h"
#import "KDTableViewSectionObject.h"
#import "NSString+Common.h"
#import "NSObject+ClassName.h"

@interface KDTableViewController ()
@property (nonatomic, strong) KDTableViewCell* protoCell;
@property (nonatomic, assign) UITableViewStyle tableStyle;

- (void)registerForKVO;
- (void)unRegisterFromKVO;
- (NSArray *)observableKeypaths;
- (void)updateUIForKeypath:(NSString *)keyPath withChange:(NSDictionary *)change;
@end

@implementation KDTableViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]){
        _tableStyle = UITableViewStylePlain;
    }
    return self;
}

- (instancetype)init
{
    return [self initWithStyle:UITableViewStylePlain];
}

- (instancetype)initWithStyle:(UITableViewStyle)style
{
    if (self = [super init]) {
        _tableStyle = style;
    }
    return self;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    if (self.tableStyle == UITableViewStyleGrouped) {
        self.tableView.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, self.tableView.bounds.size.width, 0.01f)];
    }
    
    // 没数据的时候隐藏 sperator
    self.tableView.tableFooterView = [UIView new];

    // Do any additional setup after loading the view.
    if ([self respondsToSelector:@selector(registerCellClass)]) {
        [self registerCellClass];
    }
    
    [self.view addSubview:self.tableView];
    [self.tableView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.bottom.leading.trailing.mas_equalTo(self.view);
    }];
    
    // 添加下拉刷新功能
    @weakify(self);
    [self.tableView addPullToRefreshWithActionHandler:^{
        @normalize(self);
        if ([self respondsToSelector:@selector(pullToRefreshAction)]) {
            [self pullToRefreshAction];
        }
    }];
    // 添加无限下翻功能
    [self.tableView addInfiniteScrollingWithActionHandler:^{
        @normalize(self);
        if ([self respondsToSelector:@selector(infiniteScrollingAction)]) {
            [self infiniteScrollingAction];
        }
    }];
    
    self.tableView.showsPullToRefresh = NO;
    self.tableView.showsInfiniteScrolling = NO;
    
    // KVO
//    [self registerForKVO];
}

- (void)dealloc
{
//    [self unRegisterFromKVO];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - property
- (KDTableView *)tableView
{
    if (!_tableView) {
        _tableView = [[KDTableView alloc] initWithFrame:CGRectZero style:self.tableStyle];
        _tableView.backgroundColor = [UIColor clearColor];
        _tableView.delegate = self;
        _tableView.dataSource = self;
    }
    return _tableView;
}

- (KDKVOMutableArray *)sections
{
    if (!_sections) {
        _sections = [KDKVOMutableArray new];
    }
    return _sections;
}

- (KDTableViewSectionObject *)firstSectionObject
{
    if (!_firstSectionObject) {
        _firstSectionObject = [[KDTableViewSectionObject alloc] init];
    }
    return _firstSectionObject;
}

- (KDTableViewSectionObject *)secondSectionObject
{
    if (!_secondSectionObject) {
        _secondSectionObject = [[KDTableViewSectionObject alloc] init];
    }
    return _secondSectionObject;
}

- (KDTableViewSectionObject *)thirdSectionObject
{
    if (!_thirdSectionObject) {
        _thirdSectionObject = [[KDTableViewSectionObject alloc] init];
    }
    return _thirdSectionObject;
}

- (void)setPullToRefreshView:(UIView *)pullToRefreshView
{
    _pullToRefreshView = pullToRefreshView;
    [self.tableView.pullToRefreshView setCustomView:_pullToRefreshView forState:SVPullToRefreshStateAll];
}

- (void)setInfiniteLoadView:(UIView *)infiniteLoadView
{
    _infiniteLoadView = infiniteLoadView;
    [self.tableView.infiniteScrollingView setCustomView:_infiniteLoadView forState:SVInfiniteScrollingStateAll];
}

- (id)objectAtIndexPath:(NSIndexPath *)indexPath
{
    KDTableViewSectionObject *aSectionObject = [self.sections objectAtIndex:indexPath.section];
    if (aSectionObject == nil) {
        return nil;
    }
    return [aSectionObject.items objectAtIndex:indexPath.row];
}

- (id)cellClassAtIndexPath:(NSIndexPath *)indexPath
{
    id object = [self objectAtIndexPath:indexPath];
    if (object == nil) {
        return nil;
    }
    return [self cellClassByObject:object];
}

#pragma mark - sub views
- (void)showLoading:(BOOL)show
{
    if (show)
    {
        [self showEmpty:NO];
        [self showError:NO];
        [self.loadingView setNeedsLayout];
        [self.loadingView layoutIfNeeded];
        
        [self.tableView addSubview:self.loadingView];
        [self.loadingView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.top.bottom.leading.trailing.mas_equalTo(self.tableView);
            make.width.height.mas_equalTo(self.tableView);
        }];
    } else {
        [self.loadingView removeFromSuperview];
        self.loadingView = nil;
    }
}

- (void)showError:(BOOL)show
{
    if (show)
    {
        [self showEmpty:NO];
        [self showLoading:NO];
        [self.errorView setNeedsLayout];
        [self.errorView layoutIfNeeded];
        
        [self.tableView addSubview:self.errorView];
        [self.errorView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.center.mas_equalTo(self.tableView);
            make.width.height.mas_equalTo(self.tableView);
        }];

    } else {
        [self.errorView removeFromSuperview];
        self.errorView = nil;
    }
}

- (void)showEmpty:(BOOL)show
{
    if (show)
    {
        [self showLoading:NO];
        [self showError:NO];
        [self.emptyView setNeedsLayout];
        [self.emptyView layoutIfNeeded];
        
        [self.tableView addSubview:self.emptyView];
        [self.emptyView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.center.mas_equalTo(self.tableView);
            make.width.height.mas_equalTo(self.tableView);
        }];
    } else {
        [self.emptyView removeFromSuperview];
        self.emptyView = nil;
    }
}


#pragma mark - KDTableViewControllerProtocol
// 注册cell的类型，子类实现
- (void)registerCellClass
{
    //
}

// 从object获取cell的类名
- (Class)cellClassByObject:(id)object
{
    //子类实现
    return [KDTableViewCell class];
}

- (void)didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    //子类实现
}

// 下拉刷新
- (void)pullToRefreshAction
{
    
}

// 上拉加载
- (void)infiniteScrollingAction
{
    
}


#pragma mark - UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    KDTableViewSectionObject *aSectionObject = [self.sections objectAtIndex:section];
    return [aSectionObject.items count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if ([self respondsToSelector:@selector(cellClassByObject:)]) {
        Class cls = [self cellClassAtIndexPath:indexPath];
        UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:[cls className] forIndexPath:indexPath];
        
        if ([cell isKindOfClass:[KDTableViewCell class]]) {
            [(KDTableViewCell*)cell setObject:[self objectAtIndexPath:indexPath]];
            if ([self respondsToSelector:@selector(setupControlAction:indexPath:)]) {
                [self setupControlAction:cell indexPath:indexPath];
            }
        }
        return cell;
    }
    return nil;
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView              // Default is 1 if not implemented
{
    return [self.sections count];
}

- (NSArray*)sectionIndexTitlesForTableView:(UITableView*)tableView // return list of section titles to display in section index view (e.g. "ABCD...Z#")
{
    NSMutableArray* sectionTitleArray = [NSMutableArray array];
    for (KDTableViewSectionObject* sectionObject in self.sections.innerArray) {
        if ([sectionObject letter]) {
            [sectionTitleArray addObject:[sectionObject letter]];
        }
    }
    return sectionTitleArray.count > 0 ? sectionTitleArray : nil;
}

- (NSInteger)tableView:(UITableView*)tableView sectionForSectionIndexTitle:(NSString*)title
               atIndex:(NSInteger)sectionIndex // tell table which section corresponds to section title/index (e.g. "B",1))
{
    if (sectionIndex == 0)  {
        [tableView scrollsToTop];
    }
    return sectionIndex;
}

#pragma mark - UITableViewDelegate
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    Class cls = [self cellClassAtIndexPath:indexPath];
    id object = [self objectAtIndexPath:indexPath];
    
    if ([cls shouldUseAutoLayout]) {
        if (!self.protoCell || ![self.protoCell isKindOfClass:cls]) {
            self.protoCell = [tableView dequeueReusableCellWithIdentifier:[cls className]];
        }
        [self.protoCell setObject:object];
        [self.protoCell setNeedsLayout];
        [self.protoCell layoutIfNeeded];
        
        CGSize size = [self.protoCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
        return size.height+1;
    }
    return [cls rowHeightForObject:object];
}

//- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(7_0)
//{
//    Class cls = [self cellClassAtIndexPath:indexPath];
//    return [cls estimateRowsHeight];
//}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    if ([self respondsToSelector:@selector(viewForHeaderInSection:)]) {
        UIView* sectionView = [self viewForHeaderInSection:section];
        if (sectionView == nil) {
            return 0.000001f;
        }
        [sectionView setNeedsLayout];
        [sectionView layoutIfNeeded];
        CGSize size = [sectionView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
        return size.height+1;
    }
    return 0.000001f;
}

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
    if ([self respondsToSelector:@selector(viewForFooterInSection:)]) {
        UIView* footerView = [self viewForFooterInSection:section];
        if (footerView == nil) {
            return 0.000001f;
        }
        [footerView setNeedsLayout];
        [footerView layoutIfNeeded];
        CGSize size = [footerView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
        return size.height+1;
    }
    return 0.000001f;
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
    if (self.sections.count)
    {
        KDTableViewSectionObject *sectionObject = [self.sections objectAtIndex:section];
        if (sectionObject != nil && ![NSString stringIsEmpty:sectionObject.headerTitle])
        {
            return sectionObject.headerTitle;
        }
        return sectionObject.headerTitle;
    }
    
    return nil;
}

- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section
{
    if (self.sections.count)
    {
        KDTableViewSectionObject *sectionObject = [self.sections objectAtIndex:section];
        if (sectionObject != nil && ![NSString stringIsEmpty:sectionObject.footerTitle])
        {
            return sectionObject.footerTitle;
        }
    }
    return nil;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [self didSelectRowAtIndexPath:indexPath];
}

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section   // custom view for header. will be adjusted to default or specified header height
{
    if ([self respondsToSelector:@selector(viewForHeaderInSection:)]) {
        return [self viewForHeaderInSection:section];
    }
    return nil;
}

- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section   // custom view for footer. will be adjusted to default or specified footer height
{
    if ([self respondsToSelector:@selector(viewForFooterInSection:)]) {
        return [self viewForFooterInSection:section];
    }
    return nil;
}

#pragma mark - KVO
//- (void)registerForKVO
//{
//    for (NSString *keyPath in [self observableKeypaths]) {
//        [self addObserver:self forKeyPath:keyPath options:NSKeyValueObservingOptionNew context:NULL];
//    }
//}
//
//- (void)unRegisterFromKVO
//{
//    for (NSString *keyPath in [self observableKeypaths]) {
//        [self removeObserver:self forKeyPath:keyPath];
//    }
//}
//
//- (NSArray *)observableKeypaths
//{
//    return [NSArray arrayWithObjects:@"self.sections.count", nil];
//}
//
//- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
//    if (![NSThread isMainThread]) {
//        [self performSelectorOnMainThread:@selector(updateUIForKeypath::) withObject:keyPath waitUntilDone:NO];
//    } else {
//        [self updateUIForKeypath:keyPath withChange:change];
//    }
//}
//
//- (void)updateUIForKeypath:(NSString *)keyPath withChange:(NSDictionary *)change
//{
//    if ([keyPath isEqualToString:@"self.sections.count"]) {
//        NSInteger count = [[change objectForKey:NSKeyValueChangeNewKey] integerValue];
//        if (count <= 0) {
//            if (self.emptyView) {
//                [self showEmpty:YES];
//            }
//        }
//        else
//        {
//            if (self.emptyView) {
//                [self showEmpty:NO];
//            }
//        }
//    }
//}

@end
